/*
 * PaintGrid.java
 *
 * Created on 14.02.2012, 22:42:05
 */
package recognizer;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.SwingUtilities;

/**
 * Компонент для рисования изобажения в высоком разрешении и попутном преобразовании его в низкое
 * @author Ck & FormularHunter
 */
public class PaintGrid extends javax.swing.JPanel {

    public Color GridColor = new Color(170, 170, 170);
    public Color PaintColor = Color.black;
    public Color FillColorUp = new Color(240, 240, 240);
    public Color FillColorDown = new Color(190, 190, 190);
    public int SegmentsX = 5;
    public int SegmentsY = 5;
    /**
     * Массив триггеров отражающий развёртку изображения низкого разрешения
     */
    public boolean[] checkedSegments = new boolean[SegmentsX * SegmentsY];
    /**
     * На сколько процентов должна быть заполнена клетка чтобы считалась закрашенной
     */
    public float FillThreshold = 0.12f;
    /**
     * Диаметр кисти
     */
    public int PaintSize = 20;
    /**
     * Если true - клетки будут иметь квадратную форму - иначе - растянутся на ширину компонента
     */
    public boolean isSqareSegments = false;
    private float segmentHeight;
    private float segmentWidth;
    private Point lastPoint;
    private boolean showGrid = false;
    /**
     * То что нарисовал пользователь (высокое разрешение)
     */
    private BufferedImage drawedImage = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_ARGB);

    /** Creates new form PaintGrid */
    public PaintGrid() {
        initComponents();

        ((Graphics2D) drawedImage.getGraphics()).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        Graphics2D g = (Graphics2D) (drawedImage.getGraphics());
        g.setBackground(new Color(0, 0, 0, 0));
        //g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER));

    }

    @Override
    public void paint(Graphics grphcs) {
        Graphics2D graphics2D = (Graphics2D) grphcs;
        super.paint(grphcs);
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        segmentHeight = (this.getHeight()) / SegmentsY;
        segmentWidth = (this.getWidth()) / SegmentsX;
        if (isSqareSegments) {
            segmentWidth = segmentHeight = Math.min(segmentWidth, segmentHeight);
        }
        if (showGrid) {
            //заливка
            graphics2D.setPaint(new GradientPaint(0, 0, FillColorUp, 0, getHeight(), FillColorDown));
            for (int x = 0; x < SegmentsX; x++) {
                for (int y = 0; y < SegmentsY; y++) {
                    if (checkedSegments[y * SegmentsX + x]) {
                        graphics2D.fillRect((int) (x * segmentWidth), (int) (y * segmentHeight), (int) segmentWidth, (int) segmentHeight);
                    }
                }
            }

            //grid
            graphics2D.setPaint(GridColor);
            graphics2D.setStroke(new BasicStroke(1));
            for (int i = 1; i < SegmentsX; i++) {
                graphics2D.drawLine((int) (segmentWidth * i), 0, (int) (segmentWidth * i), this.getHeight());
            }
            for (int i = 1; i < SegmentsY; i++) {
                graphics2D.drawLine(0, (int) (segmentHeight * i), this.getWidth(), (int) (segmentHeight * i));
            }
            graphics2D.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
        }

        //frame
        graphics2D.setPaint(GridColor);
        graphics2D.setStroke(new BasicStroke(1));
        graphics2D.drawRect(0, 0, getWidth() - 1, getHeight() - 1);

        //showing drawed image 
        graphics2D.drawImage(drawedImage, null, null);
    }

    /**
     * Очистка нарисованного
     */
    public void clear() {
        Graphics2D g = (Graphics2D) drawedImage.getGraphics();
        g.setBackground(new Color(0, 0, 0, 0));
        g.clearRect(0, 0, drawedImage.getWidth(), drawedImage.getHeight());
        calcFilledSegments();
        this.repaint();
    }

    public void calcFilledSegments() {
        int pixel = 0;
        int allPixelsCount = 0;
        int filledPixelsCount = 0;
        float percentFilled = 0;

        for (int x = 0; x < SegmentsX; x++) {
            for (int y = 0; y < SegmentsY; y++) {
                filledPixelsCount = 0;
                allPixelsCount = 0;
                percentFilled = 0;

                for (int pixX = (int) (x * segmentWidth); pixX < (int) ((x + 1) * segmentWidth); pixX++) {
                    for (int pixY = (int) (y * segmentHeight); pixY < (int) ((y + 1) * segmentHeight); pixY++) {
                        pixel = drawedImage.getRGB(pixX, pixY);
                        allPixelsCount++;
                        if (pixel != 0) {
                            filledPixelsCount++;
                        }
                    }
                }
                percentFilled = (float) filledPixelsCount / allPixelsCount;
                if (percentFilled > FillThreshold) {
                    checkedSegments[y * SegmentsX + x] = true;
                } else {
                    checkedSegments[y * SegmentsX + x] = false;
                }
//                System.out.print(filledPixelsCount);
//                System.out.print('/');
//                System.out.print(allPixelsCount);
//                System.out.print(' ');
//                System.out.println(percentFilled);
            }
        }
//        System.out.println(checkedSegments);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setName("Form"); // NOI18N
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                formMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                formMouseExited(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 482, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 360, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        Graphics2D g = (Graphics2D) drawedImage.getGraphics();
        if (SwingUtilities.isLeftMouseButton(evt)) {
            g.setPaint(PaintColor);

            g.setStroke(new BasicStroke(PaintSize, BasicStroke.CAP_ROUND, BasicStroke.CAP_ROUND));
            g.drawLine(lastPoint.x, lastPoint.y, evt.getPoint().x, evt.getPoint().y);
            lastPoint = evt.getPoint();

            this.repaint();
        }

    }//GEN-LAST:event_formMouseDragged

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        if (SwingUtilities.isLeftMouseButton(evt)) {
            formMouseDragged(evt);
            return;
        }
        if (SwingUtilities.isRightMouseButton(evt)) {
            clear();
        }
    }//GEN-LAST:event_formMouseClicked

    private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
        lastPoint = evt.getPoint();
    }//GEN-LAST:event_formMousePressed

    private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
        calcFilledSegments();
        repaint();
    }//GEN-LAST:event_formMouseReleased

    private void formMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseEntered
        showGrid = true;
        repaint();
    }//GEN-LAST:event_formMouseEntered

    private void formMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseExited
        showGrid = false;
        repaint();
    }//GEN-LAST:event_formMouseExited

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
        calcFilledSegments();
        repaint();
    }//GEN-LAST:event_formComponentResized
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
